/******************************************************************************* 
  Copyright (C), 1988-2020, zeno Tech. Co., Ltd.
  Description:  MEDIA模块内部头文件
  Function List:
            
*******************************************************************************/
#ifndef MEDIA_PRIV_H 
#define MEDIA_PRIV_H 

#ifdef __cplusplus
extern "C" {
#endif

/*=============================================================================
                                 Includes                                  
==============================================================================*/

#include <sys/prctl.h>
#include <netinet/in.h> 

#include "list.h"

#include "log.h"
#include "Net.h"
#include "VideoEnc.h"
#include "VideoIn.h"
#include "VideoOut.h"
#include "ini.h"
#include "VideoAnalyse.h"
#include "AudioEnc.h"
#include "AudioDec.h"
#include "led.h"
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)

#include "StreamComposeMgr.h"

/*=============================================================================
                               Macro Definition
==============================================================================*/
#define VI_WIDTH 1920
#define VI_HEIGHT 1080

#define MIRROR_WIDTH  1920
#define MIRROR_HEIGHT 1080

#define AENC_MIC_8_CHN 	     0
#define AENC_LINEIN_CHN      1
#define RTSP_AUDIO_CHN		 AENC_LINEIN_CHN

#define MIN_WIDTH 1280
#define MIN_HEIGHT 720

#define AENC_CHN 0

#define ALIGN_UP(i, n)          (((i) + (n) - 1) & ~((n) - 1))
#define ALIGN_DOWN(i, n)        ((i) & ~(n - 1))
#define ZOOM_RATE 60       

#define MEDIA_MAX(a, b) ((a>b)?a:b)
#define CONFIG_PATH "/mnt/mtd/Config/config.ini"
#define INI_SYS_PATH "/mnt/mtd/Sys/sysInfo.ini"
#define MCU_INFO_PATH "/user/mcu/mcuInfo.ini"
#define CUSTOM_PATH "/mnt/mtd/Config/customInfo.ini"
#define WLAN_INFO_PATH "/mnt/mtd/Config/wlanInfo.ini"
#define MEDIA_INFO_PATH "/mnt/mtd/Config/mediaInfo.ini"
#define DEV_HARDWARE_PATH "/mnt/mtd/Sys/hardwareTest.ini"

#define AENC_SUPPORT_CHN 	     16

#define PER_FRM_NUM 				512

#define FRAME_LEN   (PER_FRM_NUM*2)
#define MIC_NUM 5
#define SPEAKER_NUM 1
#define DATA_SIZE (8*FRAME_LEN)
#define MAX_AUDIO_CHN (1+4)

#define MAX_MEDIA_QUE_DEEP       16
#define MAX_MEDIA_BUF_LEN        (1024 * 1024)
#define MEDIA_TYPE_VIDEO         1
#define MEDIA_TYPE_AUDIO         2

#define VDEC_MAX_CHN_NUM 16

#define MAX_PCM_SIZE 8*1024

#define AUDIO_ALG_TIME 16
#define ADEC_SUPPORT_CHN         16


#define INI_NETWORK_PATH "/mnt/mtd/Config/netWork.ini"

/*=============================================================================
                        Local Structures and Typedef 
==============================================================================*/

typedef struct
{
    int zoomAbs;
    int panAbs;
    int tiltAbs;
} MEDIA_ptz_t;

typedef struct
{
    VideoAnalyser *pVideoAnalyser;
    int isStart;
    int isZoom;
    int bodyCount;
    // awi_point_t awiPoint[32];
    int pointNum;
    // awi_point_t outPoint[32];
    int outPointNum;
    pthread_mutex_t algLock;
} MEDIA_algCtl_t;

typedef struct
{
    VideoInOptions inOptions;
    VideoColor videoColor;
    int aiMode;
    int speakTrackMode;/*0,disable;1,signal,2,split*/
    int audioInState;
    int zoomAbs;
    int panAbs;
    int tiltAbs;
    int zoomTimes;
    int maxSplitCnt;
    MEDIA_ptz_t preset[2];
    int osdMirror;
    int privacy;
} MEDIA_cfg_t;

typedef struct
{
    char *pBuf[MAX_AUDIO_CHN];
    float energy[MAX_AUDIO_CHN];
    int micNum;             /* 单机mic个数+回采 */
    int frameLen;
    int audioChns;
} MEDIA_recordAudio_t;

typedef struct
{
    void *hHandle;
    MEDIA_recordAudio_t *pRecord;
} MEDIA_recordInfo_t;

typedef struct
{
    struct list_head list;
    MEDIA_recordAudio_t record;
} MEDIA_listTransfer_t;

typedef struct
{
    struct list_head list;
    char *pBuf; 
    int dataLen;
} MEDIA_listAudio_t;

typedef struct
{
    void * hAwi;
    void *hAwi40ms;
    char *pPubData;
    char *p16kData;
	
    struct list_head emptyAudio;
	struct list_head fullAudio;
	pthread_mutex_t audioLock;
	pthread_mutex_t audioMixLock;
	MEDIA_listAudio_t listAudio[16];

	struct list_head emptySrcAudio;
	struct list_head fullSrcAudio;
	pthread_mutex_t audioSrcLock;
	MEDIA_listAudio_t listSrcAudio[16];
	pthread_cond_t audioBlk;
	// awi_algo_modules_accu_t algObj;
	AudioEncDesc encDesc[AENC_SUPPORT_CHN];
	int uacConnected;
	Audio_uac_card_info uacCardInfo;
	char mixerBuf[3 * FRAME_LEN];
	// SpeexResamplerState *resampler;
	// SpeexResamplerState *mic_resampler[8];
} MEDIA_audio_t;

typedef struct
{
    int netInit;
    int isCascade;
    int linkUp;
    int upgradeState;
    struct list_head emptyAudio;
	struct list_head fullAudio;
	pthread_mutex_t audioLock;
	pthread_cond_t audioBlk;
	MEDIA_listTransfer_t listAudio[16];
	int playVol;
	int playMute;
	int record;
	int audioState;
	pthread_mutex_t transferLock;
} MEDIA_transfer_t;

typedef struct
{
    struct list_head list;
    char *pBuf;
    int len;
    int mediaType;
    int duration;
    int type;
    uint64 pts;
} MEDIA_listBufInfo_t;


typedef struct
{
    int viWidth;
    int viHeight;
    float fps;                              /* 帧率 */
    MEDIA_cfg_t cfg;
    VideoEncoder *pVideoEncoder[VDEC_MAX_CHN_NUM];    /* 编码通道句柄 */
    AudioEncoder *pAudioEncoder[AENC_SUPPORT_CHN]; 
    AudioDecoder *pAudioDecoder;
    VideoInput *pVideoInput;
    char *pEncBuf[VDEC_MAX_CHN_NUM];                       /* 帧数据缓存 */
    MEDIA_algCtl_t algCtl;
    MEDIA_audio_t audioCtl;
    MEDIA_transfer_t *pTransferCtl;
    int isUacStop;
    int uacState;
    int uvcState;
    VideoEncFormat uvcFormat;
    int uvcChn;
    int isReboot;
    int isCorr;
    int corrCalc;
    int corrVpt;
    char corrResult[8];
    int isSpeakerTest;
    int connState;
    int recordState;
    int aiAlgThdFlg;
    pthread_mutex_t algMutex;
    
	struct list_head emptyBuf;         	/* 空闲跟踪队列 */
	struct list_head fullBuf;         		/* 跟踪队列 */
	pthread_mutex_t bufLock;                       /* 队列锁 */
	MEDIA_listBufInfo_t listBuf[MAX_MEDIA_QUE_DEEP];  	/* 跟踪结果信息 */
	char mp4Name[64];
	int  isRecording;

	AudioInput* pAudioInput;
} MEDIA_ctl_t;


typedef enum {
    ENTER_STA_MODE,
    ENTER_AP_MODE,
    SET_RELAY_MODE,
    RESET_RTSP_OP,
    close_relay,
    quit
} wifi_op_cmd;


typedef struct
{
    char *pBuf;                 // 帧数据缓存
    unsigned int dataLen;       // 帧数据长度
    uint64 pts;
    int reserved[14];
} SCREEN_vencPacket_t;


typedef struct
{
    struct list_head emptyBuf;         	/* 空闲跟踪队列 */
    struct list_head fullBuf;         	/* 跟踪队列 */
    pthread_mutex_t bufLock;            /* 队列锁 */
    MEDIA_listBufInfo_t listBuf[10];  	/* 跟踪结果信息 */

} SCREEN_audioCtl_t;


/*=============================================================================
                             extern  Variables                                  
==============================================================================*/
extern MEDIA_ctl_t mediaCtl_g;

extern unsigned long long vdo_get_time();

/*=============================================================================
                             Function Definition                                  
==============================================================================*/ 
int MEDIA_UvcInit(void);

int MEDIA_HidInit(void);
int MEDIA_TransferInit(void);

int MEDIA_TransferPutAudioPlay(unsigned char *pData, int dataLen);

int MEDIA_SetPlayVol(int vol, int mute);
int MEDIA_CommonGetOsdMirror(void);

int MEDIA_CommonSetOsdMirror(int enable);
int MEDIA_CommonEnablePrivacy(int enable);
int MEDIA_CommonGetPrivacy(void);
int MEDIA_RecorderInit(void);
int MEDIA_RecorderStart_Core(void);
int MEDIA_RecorderStop_Core(void);

int MEDIA_UacVolumeFactorSet(int value);


#if 1
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
//保存文件到pathname，O_TRUNC表示打开已存在的文件，并清除文件
//len = 0;为关闭文件，使用如:video_FILE_Write("/root/test.dav", pData, dataLen);
static int media_FILE_Write(char *pathname, char *buf, int len) 
{
    static int fd = -1;
    int ret = 0;

    if (fd < 0)
    {
        fd = open(pathname, O_RDWR | O_CREAT | O_TRUNC, 0666);
        if (fd < 0)
        {
            printf("err: open %s fail, try again!\n", pathname);
            return -1;
        }
    }

    if (len == 0)
    {
        close(fd);
        fd = -1;
        printf("close %s\n", pathname);
        return 0;
    }

    ret = write(fd, buf, len);
    if (ret <= 0)
    {
        printf("err: write %s fail\n", pathname);
        return -1;
    }
    return 0;
}
#endif

#ifdef __cplusplus
}
#endif
#endif // MEDIA_PRIV_H

